package org.jeecg.modules.demo.Kingdee.Job;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.demo.DingTalk.MonthPayableOnoa.entity.MonthPayableOnoa;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptApplyRequest;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptApplyResponse;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptInfo;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptQueryRequest;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptQueryResponse;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptDownloadRequest;
import org.jeecg.modules.demo.Kingdee.Entity.ReceiptDownloadResponse;
import org.jeecg.modules.demo.Kingdee.Receipt.entity.Receipt;
import org.jeecg.modules.demo.Kingdee.Receipt.service.IReceiptService;
import org.jeecg.modules.demo.Kingdee.util.FileStorageService;
import org.jeecg.modules.demo.util.SignUtil;
import org.jeecg.modules.demo.Kingdee.util.AttachmentUploadUtil;
import org.jeecg.modules.demo.DingTalk.MonthPayableOnoa.entity.MonthPayableOnoaItem;
import org.jeecg.modules.demo.DingTalk.MonthPayableOnoa.service.IMonthPayableOnoaItemService;
import org.jeecg.modules.demo.DingTalk.MonthPayableOnoa.service.IMonthPayableOnoaService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * 从司库接口下载电子回单的定时任务类
 * 
 * 功能描述：
 * 1. 向司库系统发起电子回单申请
 * 2. 查询符合条件的电子回单列表
 * 3. 下载回单文件并保存到本地
 * 4. 将回单信息存储到数据库
 * 5. 根据外部流水号查询金蝶中的月结汇总单，获取组织和默认银行账号信息
 * 
 * 工作流程：
 * 1. 发起回单申请请求，获取clientID
 * 2. 使用clientID查询回单列表（支持分页）
 * 3. 遍历回单列表，逐个下载回单文件
 * 4. 将回单信息保存到本地数据库
 * 5. 根据外部流水号查询金蝶月结汇总单，获取组织信息和默认银行账号
 * 
 * @Author Scott
 */
@Slf4j
@Component
public class BankDownloadReceiveJob implements Job {
	
	/**
	 * 回单服务接口，用于查询和保存回单信息到数据库
	 */
	@Autowired
	private IReceiptService receiptService;
	
	/**
	 * 文件存储服务，用于保存和解压下载的回单文件
	 */
	@Autowired
	private FileStorageService fileStorageService;
	
	/**
	 * 附件上传工具类，用于上传附件到金蝶系统
	 */
	@Autowired
	private AttachmentUploadUtil attachmentUploadUtil;
	
	/**
	 * 月结汇总单子表服务接口，用于更新付款状态
	 */
	@Autowired
	private IMonthPayableOnoaItemService monthPayableOnoaItemService;
	
	/**
	 * 月结汇总单主表服务接口，用于更新主表付款状态
	 */
	@Autowired
	private IMonthPayableOnoaService monthPayableOnoaService;

	/**
	 * 定时任务执行入口方法
	 * 
	 * @param jobExecutionContext 定时任务执行上下文
	 * @throws Exception 执行过程中可能发生的异常
	 */
	@SneakyThrows
	@Override
	public void execute(JobExecutionContext jobExecutionContext) {
		// 获取当前日期
		Calendar calendar = Calendar.getInstance();

		// 格式化今天日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String todayStr = sdf.format(calendar.getTime());
		String todayStr1 = "2026-1-1";

		// 获取昨天日期
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		String yesterdayStr = sdf.format(calendar.getTime());
		String yesterdayStr1 = "2020-1-1";

		// 从任务参数中获取自定义日期参数（如果有的话）
		String parameter = jobExecutionContext.getMergedJobDataMap().getString("parameter");
		if (parameter!=null){
			yesterdayStr=parameter;
		}

		// 调用HTTP请求方法并获取返回的clientID
		String clientID = sendReceiptApplyRequest();
		log.info("请求已发送，clientID: {}", clientID);
		
		// 使用获取到的clientID发起查询请求
		if (clientID != null) {
			sendReceiptQueryRequest(clientID);
		}
		
		// 根据回单的外部流水号更新月结汇总单子表的付款状态
		// updatePaymentStatusByExternalNumbers(); // 已移除，因为现在在保存每条记录时都进行更新
	}
	
	/**
	 * 发送电子回单申请请求到司库系统
	 * 
	 * @return 返回司库系统响应的clientID，用于后续查询操作
	 */
	private String sendReceiptApplyRequest() {
        // 创建请求实体
        ReceiptApplyRequest request = new ReceiptApplyRequest();
        
        // 使用发起时间的时分秒作为ClientID 例如: 202511131412
        SimpleDateFormat clientIdFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String clientID = clientIdFormat.format(Calendar.getInstance().getTime());
        request.setClientID(clientID);
        
        request.setAccountNo("8110701013101269844"); // 示例账号
         
        // 计算30天前的日期
        LocalDate now = LocalDate.now();
        LocalDate thirtyDaysAgo = now.minusDays(30);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        
//        request.setStartDate(thirtyDaysAgo.format(formatter)); // 开始时间：30天前
//        request.setEndDate(now.format(formatter)); // 结束时间：今天
        request.setStartDate("20251118"); // 开始时间：30天前
        request.setEndDate("20251120"); // 结束时间：今天

        // 发送HTTP请求到司库系统
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 添加时间戳参数
            String timestamp = SignUtil.getCurrentTimestamp();
            
            // 构造包含签名和时间戳的请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("clientID", request.getClientID());
            requestBody.put("accountNo", request.getAccountNo());
            requestBody.put("startDate", request.getStartDate());
            requestBody.put("endDate", request.getEndDate());
            requestBody.put("timestamp", timestamp);
            
            // 生成签名
            String sign = signUtil.generateSign(requestBody);
            requestBody.put("sign", sign);
            
            String requestBodyJson = JSON.toJSONString(requestBody);
            
            HttpPost httpPost = new HttpPost("http://localhost:8080/api/receipt/apply");
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setEntity(new StringEntity(requestBodyJson, "UTF-8"));
            
            log.info("发送回单申请请求，URL: {}, 请求参数: {}", "http://localhost:8080/api/receipt/apply", requestBodyJson);
            
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                int statusCode = response.getStatusLine().getStatusCode();
                
                if (statusCode >= 200 && statusCode < 300) {
                    ReceiptApplyResponse receiptResponse = JSON.parseObject(responseBody, ReceiptApplyResponse.class);
                    if (receiptResponse != null) {
                        log.info("请求成功: status={}, statusText={}, clientID={}", 
                            receiptResponse.getStatus(), 
                            receiptResponse.getStatusText(), 
                            receiptResponse.getClientID()
                        );
                        return receiptResponse.getClientID();
                    }
                } else {
                    log.error("请求失败，HTTP状态码: {}，响应内容: {}", statusCode, responseBody);
                }
            }
        } catch (Exception e) {
            log.error("请求发生异常: ", e);
        }
        
        return clientID; // 如果请求失败，返回生成的clientID
	}
	
	/**
	 * 发送电子回单查询请求到司库系统
	 * 支持分页查询，确保能获取所有符合条件的回单数据
	 * 
	 * @param clientID 申请时返回的clientID，用于关联查询
	 */
	private void sendReceiptQueryRequest(String clientID) {
        // 设置日期参数
        LocalDate now = LocalDate.now();
        LocalDate thirtyDaysAgo = now.minusDays(30);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        String startDate = thirtyDaysAgo.format(formatter); // 开始时间：30天前
        String endDate = now.format(formatter); // 结束时间：今天
        
        // 分页处理所有数据
        int pageSize = 100; // 每页条数
        int startRecord = 1; // 起始记录号
        int totalRecords = 0; // 总记录数
        boolean firstQuery = true; // 是否为第一次查询
        
        do {
            // 创建查询请求实体
            ReceiptQueryRequest request = new ReceiptQueryRequest();
            // action和userName不需要传
            
            request.setClientID(clientID);

//        request.setStartDate(thirtyDaysAgo.format(formatter)); // 开始时间：30天前
//        request.setEndDate(now.format(formatter)); // 结束时间：今天
            request.setStartDate("20251118"); // 开始时间：30天前
            request.setEndDate("20251120"); // 结束时间：今天
            
            // 设置分页参数
            request.setStartRecord(startRecord);   // 从第几条开始
            request.setPageSize(pageSize);         // 每页条数
            request.setPageNum((startRecord - 1) / pageSize + 1);       // 页码
            request.setPageNumber(pageSize);       // 请求记录条数
            
            // 发送HTTP查询请求到司库系统
            try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
                // 添加时间戳参数
                String timestamp = SignUtil.getCurrentTimestamp();

                
                // 构造包含签名和时间戳的请求体
                Map<String, Object> requestBody = new HashMap<>();
                requestBody.put("clientID", request.getClientID());
                requestBody.put("startDate", request.getStartDate());
                requestBody.put("endDate", request.getEndDate());
                requestBody.put("startRecord", request.getStartRecord());
                requestBody.put("pageSize", request.getPageSize());
                requestBody.put("pageNum", request.getPageNum());
                requestBody.put("pageNumber", request.getPageNumber());
                requestBody.put("timestamp", timestamp);

                // 生成签名
                String sign = signUtil.generateSign(requestBody);
                requestBody.put("sign", sign);
                String requestBodyJson = JSON.toJSONString(requestBody);
                
                HttpPost httpPost = new HttpPost("http://localhost:8080/api/receipt/query");
                httpPost.setHeader("Content-Type", "application/json");
                httpPost.setEntity(new StringEntity(requestBodyJson, "UTF-8"));
                
                log.info("发送回单查询请求，URL: {}, 请求参数: {}", "http://localhost:8080/api/receipt/query", requestBodyJson);
                
                try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                    String responseBody = EntityUtils.toString(response.getEntity());
                    int statusCode = response.getStatusLine().getStatusCode();
                    
                    if (statusCode >= 200 && statusCode < 300) {
                        ReceiptQueryResponse receiptResponse = JSON.parseObject(responseBody, ReceiptQueryResponse.class);
                        if (receiptResponse != null) {
                            log.info("查询请求成功: status={}, statusText={}, totalRecords={}, returnRecords={}", 
                                receiptResponse.getStatus(), 
                                receiptResponse.getStatusText(), 
                                receiptResponse.getTotalRecords(),
                                receiptResponse.getReturnRecords()
                            );
                            
                            // 获取总记录数（只在第一次查询时获取）
                            if (firstQuery) {
                                totalRecords = receiptResponse.getTotalRecords();
                                firstQuery = false;
                            }
                            
                            // 保存回单列表到数据库并下载回单文件
                            saveReceiptsToDatabase(receiptResponse.getUserDataList());
                            
                            // 更新起始记录号，准备下一页查询
                            startRecord += pageSize;
                        }
                    } else {
                        log.error("查询请求失败，HTTP状态码: {}，响应内容: {}", statusCode, responseBody);
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("查询请求发生异常: ", e);
                break;
            }
        } while (startRecord <= totalRecords);
	}
	@Autowired
	SignUtil signUtil;
	/**
	 * 发送电子回单下载请求到司库系统
	 * 
	 * @param rcptNum 回单编号，用于指定要下载的回单
	 * @return 文件保存路径，如果下载失败则返回null
	 */
    private String sendReceiptDownloadRequest(String rcptNum) {
        // 创建下载请求实体
        ReceiptDownloadRequest request = new ReceiptDownloadRequest();
        // action和userName不需要传
        
        // 构造只包含一个回单编号的列表
        List<ReceiptInfo> downloadReceiptInfos = new ArrayList<>();
        ReceiptInfo downloadReceiptInfo = new ReceiptInfo();
        downloadReceiptInfo.setRcptNum(rcptNum);
        downloadReceiptInfos.add(downloadReceiptInfo);
        
        request.setUserDataList(downloadReceiptInfos);
        
        // 发送HTTP下载请求到司库系统
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 添加时间戳参数
            String timestamp = SignUtil.getCurrentTimestamp();

            // 生成签名（使用新的专用方法）
            String sign = SignUtil.generateDownloadSign(timestamp, downloadReceiptInfos);
            
            // 构造包含签名和时间戳的请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("userDataList", request.getUserDataList());
            requestBody.put("timestamp", timestamp);
            requestBody.put("sign", sign);
            String requestBodyJson = JSON.toJSONString(requestBody);
            
            HttpPost httpPost = new HttpPost("http://localhost:8080/api/receipt/download");
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setEntity(new StringEntity(requestBodyJson, "UTF-8"));
            
            log.info("发送回单下载请求，URL: {}, 请求参数: {}", "http://localhost:8080/api/receipt/download", requestBodyJson);
            
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                int statusCode = response.getStatusLine().getStatusCode();
                
                if (statusCode >= 200 && statusCode < 300) {
                    ReceiptDownloadResponse receiptResponse = JSON.parseObject(responseBody, ReceiptDownloadResponse.class);
                    if (receiptResponse != null) {
                        log.info("下载请求成功: status={}, statusText={}, fileName={}", 
                            receiptResponse.getStatus(), 
                            receiptResponse.getStatusText(), 
                            receiptResponse.getFileName()
                        );
                        
                        // 保存并解压回单文件
                        if (receiptResponse.getFileContent() != null && !receiptResponse.getFileContent().isEmpty()) {
                            return fileStorageService.saveAndExtractReceiptFile(receiptResponse.getFileContent());
                        }
                    }
                } else {
                    log.error("下载请求失败，HTTP状态码: {}，响应内容: {}", statusCode, responseBody);
                }
            }
        } catch (Exception e) {
            log.error("下载请求发生异常: ", e);
        }
        
        return null;
    }
	
	/**
	 * 保存并解压回单文件（此方法目前未被使用，功能已在fileStorageService中实现）
	 * 
	 * @param fileData 文件数据
	 * @param fileName 文件名
	 * @return 文件保存路径
	 */
	private String saveAndExtractReceiptFile(byte[] fileData, String fileName) {
		try {
			// 使用FileStorageService保存文件
			String fileContent = java.util.Base64.getEncoder().encodeToString(fileData);
			return fileStorageService.saveAndExtractReceiptFile(fileContent);
		} catch (IOException e) {
			log.error("保存文件时发生错误", e);
			return null;
		}
	}
	
	/**
	 * 将回单列表保存到数据库
	 * 对于每个回单，会先检查是否已存在，避免重复保存
	 * 同时会下载对应的回单文件并保存文件路径
	 * 
	 * @param receiptInfoList 回单信息列表
	 */
	private void saveReceiptsToDatabase(List<ReceiptInfo> receiptInfoList) {
		if (receiptInfoList == null || receiptInfoList.isEmpty()) {
			log.info("没有回单数据需要保存");
			return;
		}
		
		int savedCount = 0;
		for (ReceiptInfo receiptInfo : receiptInfoList) {
			try {
				if(receiptInfo.getExternalNum()==null){
					log.info("回单externalNum为空");
					continue;
				}
				// 检查回单是否已存在，通过回单编号进行判断
				Receipt existingReceipt = receiptService.getOne(
					new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Receipt>()
						.eq("rcptnum", receiptInfo.getRcptNum())
				);
				
				// 只有当回单不存在时才进行保存操作
				if (existingReceipt == null) {
					// 创建新的回单记录
					Receipt receipt = new Receipt();
					receipt.setRcptnum(receiptInfo.getRcptNum()); // 回单编号
					receipt.setSumtranno(receiptInfo.getSumTranNo()); // 系统交易流水号
					receipt.setExternalnum(receiptInfo.getExternalNum()); // 外部请求流水号
					
					// 下载回单文件并更新path字段
					String filePath = sendReceiptDownloadRequest(receiptInfo.getRcptNum());
					receipt.setPath(filePath != null ? filePath : ""); // 存储目录
					receipt.setStatus("未上传"); // 设置回单状态为已上传
					
					// 根据外部流水号查询金蝶月结汇总单，获取组织信息和默认银行账号
					String externalNum = receiptInfo.getExternalNum();
					if (externalNum != null && !externalNum.isEmpty()) {
						K3CloudApi api = new K3CloudApi();
						String orgInfo = getOrganizationInfoByExternalNum(externalNum, api);
						String defaultBankAccount = getDefaultBankAccountByOrg(orgInfo, api);
						
						log.info("外部流水号 {} 对应的组织信息: {}, 默认银行账号: {}", externalNum, orgInfo, defaultBankAccount);
						// 这里可以将组织信息和银行账号保存到receipt对象中，如果需要的话
					}
					
					// 保存到数据库
					receiptService.save(receipt);
					savedCount++;
					
					// 保存一张回单记录后，立即查找金蝶系统中匹配的单据体数据并更新状态
					updateKingdeeDocumentStatus(externalNum, receipt.getPath());
				}
			} catch (Exception e) {
				log.error("保存回单信息时发生错误，回单编号: {}", receiptInfo.getRcptNum(), e);
			}
		}
		
		log.info("成功保存 {} 条回单记录到数据库", savedCount);
	}
	
	/**
	 * 根据外部流水号查询金蝶月结汇总单，获取组织信息
	 * 
	 * @param externalNum 外部流水号
	 * @param api 金蝶API实例
	 * @return 组织编码
	 */
	private String getOrganizationInfoByExternalNum(String externalNum, K3CloudApi api) {
		try {
			// 构造查询条件，根据外部流水号查询月结汇总单
			String filterString = "F_externalNum = '" + externalNum + "'";
			String fieldKeys = "FID,FBillNo,F_NHOV_OrgId_83g.FNUMBER";
			
			// 构造查询JSON
			String queryJson = String.format(
				"{\"FormId\":\"NHOV_MONTH_PAYABLE\",\"FieldKeys\":\"%s\",\"FilterString\":\"%s\",\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":1}",
				fieldKeys, filterString
			);
			
			log.info("开始查询金蝶月结汇总单，查询条件: {}", filterString);
			
			// 执行查询
			String resultStr = api.billQuery(queryJson);
			
			// 解析查询结果
			List<JSONObject> resultList = JSONArray.parseArray(resultStr, JSONObject.class);
			
			if (!resultList.isEmpty()) {
				JSONObject item = resultList.get(0);
				String orgNumber = item.getString("F_NHOV_OrgId_83g.FNUMBER");
				log.info("查询到月结汇总单，外部流水号: {}, 组织编码: {}", externalNum, orgNumber);
				return orgNumber;
			} else {
				log.warn("未找到外部流水号 {} 对应的月结汇总单", externalNum);
				return null;
			}
		} catch (Exception e) {
			log.error("根据外部流水号 {} 查询月结汇总单时发生错误: ", externalNum, e);
			return null;
		}
	}
	
	/**
	 * 根据组织编码获取默认银行账号
	 * 
	 * @param orgNumber 组织编码
	 * @param api 金蝶API实例
	 * @return 默认银行账号
	 */
	private String getDefaultBankAccountByOrg(String orgNumber, K3CloudApi api) {
		try {
			if (orgNumber == null || orgNumber.isEmpty()) {
				log.warn("组织编码为空，无法查询默认银行账号");
				return null;
			}
			
			// 构造查询条件，根据组织编码和默认银行账号标识查询银行账号
			String filterString = "FISDEFAULTBANK = '1' AND FUseOrgId.FNumber = '" + orgNumber + "'";
			String fieldKeys = "FNumber";
			
			// 构造查询JSON
			String queryJson = String.format(
				"{\"FormId\":\"CN_BANKACNT\",\"FieldKeys\":\"%s\",\"FilterString\":\"%s\",\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":1}",
				fieldKeys, filterString
			);
			
			log.info("开始查询默认银行账号，查询条件: {}", filterString);
			
			// 执行查询
			String resultStr = api.billQuery(queryJson);
			
			// 解析查询结果
			List<JSONObject> resultList = JSONArray.parseArray(resultStr, JSONObject.class);
			
			if (!resultList.isEmpty()) {
				JSONObject item = resultList.get(0);
				String bankAccount = item.getString("FNumber");
				log.info("查询到组织 {} 的默认银行账号: {}", orgNumber, bankAccount);
				return bankAccount;
			} else {
				log.warn("未找到组织 {} 的默认银行账号", orgNumber);
				return null;
			}
		} catch (Exception e) {
			log.error("查询组织 {} 的默认银行账号时发生错误: ", orgNumber, e);
			return null;
		}
	}
	
	/**
	 * 根据外部流水号更新金蝶单据状态并上传附件
	 * 
	 * @param externalNum 外部流水号
	 * @param filePath 文件路径
	 */
	private void updateKingdeeDocumentStatus(String externalNum, String filePath) {
		try {
			if (externalNum == null || externalNum.isEmpty()) {
				log.warn("外部流水号为空，无法更新金蝶单据状态");
				return;
			}
			
			// 初始化金蝶API
			K3CloudApi api = new K3CloudApi();
			
			// 根据FSupplier_S_EXTNUM查询金蝶月结付款单的单据体数据
			String filterString = "FSupplier_S_EXTNUM = '" + externalNum + "'";
			String fieldKeys = "FSupplier_BankSta_FEntryID,FID";
			
			// 构造查询JSON
			String queryJson = String.format(
				"{\"FormId\":\"NHOV_MONTH_PAYABLE\",\"FieldKeys\":\"%s\",\"FilterString\":\"%s\",\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":1}",
				fieldKeys, filterString
			);
			
			log.info("开始查询金蝶月结付款单，查询条件: {}", filterString);
			
			// 执行查询
			String resultStr = api.billQuery(queryJson);
			
			// 解析查询结果
			List<JSONObject> resultList = JSONArray.parseArray(resultStr, JSONObject.class);
			
			if (!resultList.isEmpty()) {
				JSONObject item = resultList.get(0);
				String entryId = item.getString("FSupplier_BankSta.FEntryID");
				String fid = item.getString("FID");
				
				log.info("查询到月结付款单，外部流水号: {}, EntryID: {}, FID: {}", externalNum, entryId, fid);
				
				// 上传附件到主表
				if (filePath != null && !filePath.isEmpty() ) {
					uploadAttachmentToKingdee(fid, filePath, api);
				}
				
				// 更新单据体状态字段
				updateKingdeeEntryStatus(entryId, fid, api);
			} else {
				log.warn("未找到外部流水号 {} 对应的月结付款单", externalNum);
			}
		} catch (Exception e) {
			log.error("根据外部流水号 {} 更新金蝶单据状态时发生错误: ", externalNum, e);
		}
	}
	
	/**
	 * 上传附件到金蝶单据
	 * 
	 * @param parentId 主表FID
	 * @param filePath 文件路径
	 * @param api 金蝶API实例
	 */
	private void uploadAttachmentToKingdee(String parentId, String filePath, K3CloudApi api) {
		try {
			if (filePath == null || filePath.isEmpty() || parentId == null || parentId.isEmpty()) {
				log.warn("文件路径或主表ID为空，无法上传附件");
				return;
			}
			
			// 获取文件名
			String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
			
			// 读取文件内容
			java.nio.file.Path path = java.nio.file.Paths.get(filePath);
			java.io.InputStream inputStream = java.nio.file.Files.newInputStream(path);
			
			// 上传附件到金蝶系统
			attachmentUploadUtil.uploadAttachment(
				fileName,                // 文件名
				"NHOV_MONTH_PAYABLE",    // 表单ID
				"",                      // 单据编号（可为空）
				parentId,                // 主表FID
				inputStream              // 文件输入流
			);
			
			log.info("成功上传附件到金蝶单据，主表ID: {}, 文件名: {}", parentId, fileName);
		} catch (Exception e) {
			log.error("上传附件到金蝶单据时发生错误，主表ID: {}", parentId, e);
		}
	}
	
	/**
	 * 更新金蝶单据体状态字段
	 * 
	 * @param entryId 单据体FEntryID
	 * @param parentId 主表FID
	 * @param api 金蝶API实例
	 */
	private void updateKingdeeEntryStatus(String entryId, String parentId, K3CloudApi api) {
		try {
			// 构造更新JSON
			String updateJson = String.format(
				"{\n" +
				"  \"NeedUpDateFields\": [\n" +
				"    \"FSupplier_S_BankSta\",\n" +
				"    \"FSupplier_S_Receip\"\n" +
				"  ],\n" +
				"  \"Model\": {\n" +
				"    \"FID\": \"%s\",\n" +
				"    \"FEntity\": [\n" +
				"      {\n" +
				"        \"FEntryID\": \"%s\",\n" +
				"        \"FSupplier_S_BankSta\": \"已付款\",\n" +
				"        \"FSupplier_S_Receip\": \"已上传\"\n" +
				"      }\n" +
				"    ]\n" +
				"  }\n" +
				"}",
				parentId, entryId
			);

			log.info("开始更新金蝶单据体状态，更新JSON: {}", updateJson);

			// 执行更新操作
			String resultStr = api.save("NHOV_MONTH_PAYABLE", updateJson);

			log.info("更新金蝶单据体状态结果: {}", resultStr);

			// 解析结果
			JSONObject result = JSONObject.parseObject(resultStr);
			if (result != null && result.containsKey("Result")) {
				JSONObject resultObj = result.getJSONObject("Result");
				if (resultObj != null && resultObj.containsKey("ResponseStatus")) {
					JSONObject responseStatus = resultObj.getJSONObject("ResponseStatus");
					boolean isSuccess = responseStatus.getBoolean("IsSuccess");

					if (isSuccess) {
						log.info("成功更新金蝶单据体状态，EntryID: {}", entryId);
					} else {
						log.error("更新金蝶单据体状态失败，EntryID: {}, 结果: {}", entryId, resultStr);
					}
				}
			}
		} catch (Exception e) {
			log.error("更新金蝶单据体状态时发生错误，EntryID: {}", entryId, e);
		}
	}
	
	/**
	 * 根据单个外部流水号更新月结汇总单子表的付款状态
	 * 
	 * @param externalNum 外部流水号
	 */
	private void updatePaymentStatusByExternalNumber(String externalNum) {
		try {
			if (externalNum == null || externalNum.isEmpty()) {
				log.warn("外部流水号为空，无法更新付款状态");
				return;
			}
			
			// 查询本地子表中extno匹配的记录
			List<MonthPayableOnoaItem> items = monthPayableOnoaItemService.list(
				new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<MonthPayableOnoaItem>()
					.eq("extno", externalNum)
					.ne("pay_status", "已付款")
			);
			
			if (!items.isEmpty()) {
				for (MonthPayableOnoaItem item : items) {
					// 更新付款状态为"已付款"
					item.setPayStatus("已付款");
					monthPayableOnoaItemService.updateById(item);
					log.info("更新子表记录 {} 的付款状态为已付款，外部流水号: {}", item.getId(), externalNum);
				}
				
				// 检查主表记录是否所有子表记录都已付款
				checkAndUpdateMainRecordStatus(items.get(0).getMainId());
			} else {
				log.debug("未找到外部流水号 {} 对应的未付款记录", externalNum);
			}
		} catch (Exception e) {
			log.error("处理外部流水号 {} 时发生错误: ", externalNum, e);
		}
	}
	
	/**
	 * 检查主表记录关联的所有子表记录是否都已付款，如果是则更新主表状态为已付款
	 * 
	 * @param mainId 主表记录ID
	 */
	private void checkAndUpdateMainRecordStatus(String mainId) {
		try {
			if (mainId == null || mainId.isEmpty()) {
				log.warn("主表ID为空，无法检查主表状态");
				return;
			}
			
			// 查询主表记录
			MonthPayableOnoa mainRecord = monthPayableOnoaService.getById(mainId);
			if (mainRecord == null) {
				log.warn("未找到主表记录，ID: {}", mainId);
				return;
			}
			
			// 查询该主表关联的所有子表记录
			List<MonthPayableOnoaItem> allItems = monthPayableOnoaItemService.list(
				new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<MonthPayableOnoaItem>()
					.eq("main_id", mainId)
			);
			
			// 检查是否所有子表记录都已付款
			boolean allPaid = true;
			for (MonthPayableOnoaItem item : allItems) {
				if (!"已付款".equals(item.getPayStatus())) {
					allPaid = false;
					break;
				}
			}
			
			// 如果所有子表记录都已付款，且主表付款状态不是"已付款"，则更新主表状态
			if (allPaid && !"已付款".equals(mainRecord.getPayStatus())) {
				mainRecord.setPayStatus("已付款");
				monthPayableOnoaService.updateById(mainRecord);
				log.info("主表记录 {} 的付款状态已更新为已付款", mainId);
			}
		} catch (Exception e) {
			log.error("检查并更新主表记录状态时发生错误，主表ID: {}", mainId, e);
		}
	}
}
